package com.echo.im.engin.netty.handler;

import com.echo.im.engin.event.entity.UserOfflineEvent;
import com.echo.im.engin.netty.context.ChannelAttrKey;
import com.echo.im.infrastructure.session.UserChannelMap;
import com.echo.im.infrastructure.util.SpringContextHolder;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;

/**
 *
 * @author echo
 * @date 2024-08-16
 */
@Slf4j
public class DisconnectHandler extends ChannelInboundHandlerAdapter {

    /**
     * 避免误删：防止异地登录后UserChannelCtxMap中的USER_ID，TERMINAL_TYPE已经被替换成了别人的Channel
     * 所以删除的时候要保证只能删除自己的Channel
     * @param ctx
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        AttributeKey<Long> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID);
        Long userId = ctx.channel().attr(userIdAttr).get();
        AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE);
        Integer terminal = ctx.channel().attr(terminalAttr).get();
        Channel channel= UserChannelMap.getChannel(userId, terminal);
        if(channel!=null&&channel.id()==ctx.channel().id()){
            // 移除channel
            UserChannelMap.removeChannel(userId, terminal);

            ApplicationEventPublisher applicationEventPublisher = SpringContextHolder.getApplicationEventPublisher();
            applicationEventPublisher.publishEvent(new UserOfflineEvent(userId, terminal));

            log.info("断开连接,userId:{},终端类型:{},{}", userId, terminal, ctx.channel().id().asLongText());
        }
        super.channelInactive(ctx);
    }
}
